home *** CD-ROM | disk | FTP | other *** search
- PROGRAM PDIR;
- {$R+ $V+ $K+ }
- TYPE
- byte4 = ARRAY [1..4] OF BYTE;
- txt = STRING[255];
-
- ENTRY = RECORD
- filename : ARRAY[1..8] OF BYTE;
- ext : ARRAY[1..3] OF BYTE;
- attr : BYTE;
- reserve : ARRAY[1..10] OF BYTE;
- cr_time : INTEGER;
- cr_date : INTEGER;
- fat_start : INTEGER;
- file_size : byte4;
- END;
-
- dir_type = ARRAY [1..16] OF entry;
-
- TYPE standardarray = ARRAY[1..512] OF STRING[8];
- TYPE pointarray = ARRAY[1..512] OF INTEGER;
-
-
- VAR
- fat_fill : ARRAY[0..4095] OF BYTE;
- dir : dir_type;
- pointer : pointarray;
- cluster : ARRAY [1..50] OF INTEGER;
- father,son : ARRAY [0..50] OF BYTE;
- i,j,k : INTEGER;
- hour,min,sec,
- month,day,date : BYTE;
- year : INTEGER;
- side,track,sector : BYTE;
- no_dir : INTEGER;
- no_words : INTEGER;
- no_entry : INTEGER;
- no_lines,no_max : INTEGER;
- dir_name : ARRAY[1..50] OF STRING[50];
- dir_root : STRING[20];
- dir_num,dir_point : INTEGER;
- parent : INTEGER;
- size : REAL;
- drive,cl_size,
- no_sect,
- first_clust,
- no_side : BYTE;
- first_dir : BYTE;
- no_root : REAL;
-
- file_name : standardarray;
- ext_name : ARRAY [1..512] OF STRING[3];
- fn_time : ARRAY [1..512] OF INTEGER;
- fn_date : ARRAY [1..512] OF INTEGER;
- fn_size : ARRAY [1..512] OF byte4;
-
- vol_id : STRING[11];
- one_on,want_border : BOOLEAN;
- want_hidden : BOOLEAN;
- want_dir : BOOLEAN;
- want_deleted : BOOLEAN;
- compressed : BOOLEAN;
- response : INTEGER;
- alpha : STRING[1];
- drive_no : INTEGER;
- border : STRING[80];
- top_border : STRING[80];
- left_border : STRING[5];
- right_border : STRING[5];
- side_border : STRING[1];
- outfil_name : STRING[20];
- outfil : TEXT;
- ff,comp,EXP,
- LL8,cancel : STRING[2];
- short : STRING[3];
- free_clusters : INTEGER;
- total_clusters : INTEGER;
- free_space : REAL;
- total_size : REAL;
-
- {$i biosread.inc}
- {$i getfree.inc}
- {$i getdate.inc}
-
-
- PROCEDURE getfntime(VAR hour,min,sec :BYTE ; cr_time:INTEGER);
- VAR
- scratch : INTEGER;
-
- BEGIN
- scratch := cr_time SHR 5;
- min := scratch MOD 64;
- hour := scratch DIV 64;
- sec := abs(cr_time) MOD 32;
- sec := sec * 2;
- END;
-
- PROCEDURE getfndate(VAR year: INTEGER;
- VAR month,day :BYTE;
- cr_date:INTEGER);
-
- BEGIN
- year := 80 + (cr_date DIV 512);
- month:= (cr_date MOD 512) DIV 32;
- day := cr_date MOD 32;
- END;
-
- PROCEDURE getfnsize(VAR size:REAL; file_size:byte4);
-
- BEGIN
- size := file_size[1];
- size := size + 256.*file_size[2];
- size := size + 65536.*file_size[3];
- size := size + 256.*65536.*file_size[4];
- END;
-
- FUNCTION fill_string(char_fill: txt ; no_char:BYTE): txt;
-
- VAR
- i : INTEGER;
- newstring : txt;
-
- BEGIN
-
- newstring := '';
-
- FOR i := 1 TO no_char DO
- newstring := CONCAT(newstring,char_fill);
-
- fill_string := newstring;
-
- END;
-
- FUNCTION concatc(VAR chars; no_char:BYTE): txt;
-
- TYPE
- ch_array = ARRAY[1..255] OF BYTE;
-
- VAR
- i : INTEGER;
- newchars : ch_array ABSOLUTE chars;
- newstring : txt;
-
- BEGIN
-
- newstring := '';
-
- FOR i := 1 TO no_char DO
- newstring := CONCAT(newstring,CHR(newchars[i]));
-
- concatc := newstring;
-
- END;
-
- PROCEDURE read_dir (VAR dir:dir_type;
- clust1 :INTEGER ; no_cluster:REAL);
- VAR
- lend : BOOLEAN;
- clust : INTEGER;
- fat_cluster,fat_offset : INTEGER;
-
- BEGIN
-
-
- no_words:= 0;
- clust := clust1;
-
- lend := FALSE;
-
- i := 0;
- WHILE NOT lend DO
- BEGIN
-
- i := i + 1;
-
-
- sector := clust MOD no_sect + 1;
- side := (clust DIV no_sect) MOD no_side;
- track := clust DIV (no_side*no_sect);
-
- biosread(dir[1],drive,side,track,sector,1);
-
-
- FOR j := 1 TO 16 DO
- BEGIN
-
- WITH dir[j] DO
- BEGIN
-
- IF filename[1] = $00 THEN
- lend := TRUE;
- IF (filename[1] <> $00) AND
- ( (filename[1] <> $e5) OR want_deleted ) THEN
- BEGIN
-
-
- IF ( ( (attr AND 2) <> 2) OR want_hidden ) AND
- ( ( (attr AND 16) <> 16) OR want_dir) AND
- ( ( (attr AND 8) <> 8) OR want_dir)
- THEN
- BEGIN
-
- no_words := no_words+1;
- file_name[no_words] :=concatc(filename,8);
- ext_name[no_words] :=concatc(ext,3);
- fn_time[no_words] := cr_time;
- fn_date[no_words] := cr_date;
- fn_size[no_words] := file_size;
-
- END;
-
- IF ( (attr AND 8) = 08) THEN
- BEGIN
- vol_id := CONCAT( concatc(filename,8) ,
- concatc(ext,3) );
- WRITE(outfil,left_border,EXP,
- ' VOLUME NAME IS: ',VOL_ID);
- IF LENGTH(cancel) <> 0 THEN
- WRITELN(outfil,cancel,right_border:18)
- ELSE
- WRITELN(outfil,right_border:43);
-
- no_lines := no_lines + 1;
- END;
-
- IF ( (attr AND 16) = 16) AND (CHR(filename[1]) <> '.')
- AND ( filename[1] <> $e5 ) THEN
- BEGIN
-
- dir_num := dir_num + 1;
- dir_name[dir_num] := dir_name[parent] +
- concatc(filename,8) + '\' ;
- father[dir_num] := parent;
-
- IF son[parent] = 0 THEN
- son[parent] := dir_num;
-
- cluster[dir_num] := fat_start*cl_size + first_clust;
-
- END;
- END; { good entries}
-
-
-
- END; {all entries}
- END; {directory loop}
- clust := clust + 1;
- IF ( i >= (no_cluster*cl_size) ) AND (no_cluster = 1.0) THEN
- BEGIN
- clust1 := (clust1 - first_clust) DIV cl_size;
- fat_offset := (clust1*3) DIV 2;
- IF clust1 MOD 2 = 0 THEN
-
- fat_cluster := fat_fill[fat_offset] +
- ( (fat_fill[fat_offset+1] MOD 16 ) * 256)
-
- ELSE
- fat_cluster := (fat_fill[fat_offset] SHR 4 ) +
- (fat_fill[fat_offset+1] * 16);
-
- IF fat_cluster > $ff0 THEN
- lend := TRUE
-
- ELSE
- BEGIN
- clust1 := fat_cluster*cl_size + first_clust;
- clust := clust1;
- i := 0;
- END;
- END;
- END; {lend}
- END; {read_dir}
-
-
-
- PROCEDURE SWAP( VAR a,b: INTEGER );
- VAR t: INTEGER;
- BEGIN
- t := a;
- a := b;
- b := t
- END;
-
-
- PROCEDURE bsort( start, top: INTEGER;
- VAR arry: standardarray;
- VAR pointer: pointarray );
- {bubble sort procedure. sorts array from start to top inclusive}
- VAR index: INTEGER;
- switched: BOOLEAN;
- BEGIN {bsort}
- REPEAT
- switched := FALSE;
- FOR index := start TO top-1 DO
- BEGIN
- IF arry[pointer[index]] > arry[pointer[index+1]] THEN
- BEGIN
- SWAP( pointer[index] , pointer[index+1] );
- switched := TRUE;
- END
- END;
- UNTIL switched = FALSE;
- END; {bsort}
-
- PROCEDURE findmedian( start, top: INTEGER;
- VAR arry: standardarray;
- VAR pointer : pointarray );
- {procedure to find a good median value in array and place it}
- VAR middle: INTEGER;
- sorted: ARRAY [1..3] OF STRING[8];
- BEGIN {findmedian}
- middle := (start + top) DIV 2;
- sorted[1] := arry[pointer[start]];
- sorted[2] := arry[pointer[top]];
- sorted[3] := arry[pointer[middle]];
-
- IF (sorted[2] > sorted[1]) AND (sorted[2] < sorted[3]) THEN
- SWAP( pointer[start], pointer[middle] )
- ELSE IF (sorted[3] > sorted[1]) AND (sorted[3] < sorted[2]) THEN
- SWAP( pointer[start], pointer[top] );
- END; {findmedian}
-
- PROCEDURE sortsection( start, top: INTEGER;
- VAR arry: standardarray;
- VAR pointer : pointarray);
- {procedure to sort a section of the main array, and }
- {then divide it into two partitions to be sorted }
- VAR swapup: BOOLEAN;
- s,e,m: INTEGER;
- BEGIN {sortsection}
- IF top - start < 6 THEN {sort small sections with bsort}
- bsort( start, top, arry , pointer )
- ELSE
- BEGIN
- findmedian( start, top, arry , pointer );
- swapup := TRUE;
- {start scanning from array top}
- s := start; {lower comparison limit}
- e := top; {upper comparison limit}
- m := start; {location of comparison value}
- WHILE e > s DO
- BEGIN
- IF swapup = TRUE THEN
- {scan downward from partition top}
- {and exchange if smaller than median}
- BEGIN
- WHILE( arry[pointer[e]] >= arry[pointer[m]] )
- AND (e > m) DO
- e := e - 1;
- IF e > m THEN
- BEGIN
- SWAP( pointer[e], pointer[m] );
- m := e;
- END;
- swapup := FALSE;
- END
- ELSE
- {scan upward from a partition start}
- {and exchange if larger than median}
- BEGIN
- WHILE( arry[pointer[s]] <= arry[pointer[m]] )
- AND (s < m) DO
- s := s + 1;
- IF s < m THEN
- BEGIN
- SWAP( pointer[s], pointer[m] );
- m := s;
- END;
- swapup := TRUE;
- END
- END;
- {sort lower half of partition}
- sortsection( start, m-1, arry , pointer );
- {sort upper half of partition}
- sortsection( m+1, top, arry , pointer);
- END
- END; {sortsection}
-
- PROCEDURE sort_dir (VAR file_name:standardarray; no_words:INTEGER);
-
- BEGIN {qsort - main program}
-
- FOR i := 1 TO no_words DO
- pointer[i] := i;
-
-
- sortsection( 1, no_words , file_name , pointer );
-
- no_entry := (no_words+1) DIV 2;
-
- IF no_lines + no_entry + 6 > no_max THEN
- BEGIN
-
- FOR i := no_lines TO no_max-1 DO
- IF want_border THEN
- WRITELN(outfil,border);
-
- no_lines := 0;
- IF want_border THEN
- WRITELN(outfil,top_border);
- CLRSCR;
- WRITE(outfil,ff);
- IF want_border THEN
- WRITELN(outfil,top_border);
- END;
-
-
- WRITE(outfil,left_border,' ',EXP);
- WRITE(outfil,'Directory:',dir_name[dir_point],
- fill_string(' ',26-LENGTH(dir_name[dir_point]) ));
- IF LENGTH(cancel) <> 0 THEN
- WRITELN(outfil,cancel,right_border)
- ELSE
- WRITELN(outfil,right_border:45);
-
- WRITELN(outfil,border);
- WRITELN(outfil,border);
- total_size := 0;
-
- FOR j := 1 TO no_entry DO
- BEGIN
-
- WRITE(outfil,left_border);
-
- FOR i := 0 TO 1 DO
- BEGIN
-
- IF j+i*no_entry <= no_words THEN
- BEGIN
-
- k := pointer[j+i*no_entry];
-
- getfntime(hour,min,sec,fn_time[k]);
- getfndate(year,month,day,fn_date[k]);
- getfnsize(size,fn_size[k]);
-
- total_size := total_size +
- (cl_size*512) * INT( size/(cl_size*512) + 0.99 );
-
- IF (size = 0) AND ( POS('.',file_name[k]) <> 1 ) THEN
- total_size := total_size + cl_size*512;
-
-
- WRITE(outfil,file_name[k],'.',
- ext_name[k]);
-
- WRITE(outfil,' ',month:2,'/',day:2,'/',year:2,
- ' ',hour:2,':',(min DIV 10):1,(min MOD 10):1,
- size:7:0);
-
- IF i = 0 THEN
- WRITE(outfil,' ');
-
- END
- ELSE
- WRITE(outfil,' ':35);
- END;
- WRITELN(outfil,right_border);
- END;
-
- WRITELN(outfil,left_border,' ':38,'TOTAL SIZE: ',' ':15,
- total_size:8:0,right_border);
-
- WRITELN(outfil,border);
- WRITELN(outfil,border);
- no_lines := no_lines + no_entry + 6;
-
- END; {qsort}
-
-
- PROCEDURE setup(drive_no:INTEGER);
- BEGIN
- comp := CHR(15);
- EXP := CHR(14);
- cancel := CHR(20);
- ff := CHR(12);
- LL8 := CHR(27)+CHR(48);
- short:= CHR(27)+'C'+CHR(44);
-
- IF NOT compressed THEN comp := '';
- IF (outfil_name <> 'LPT1:') AND (outfil_name <> 'lpt1:') THEN
- BEGIN
- comp := '';
- EXP := '';
- cancel := '';
- { ff := ''; GO AHEAD AND DO A FORM FEED }
- LL8 := '';
- short := '';
- END;
-
-
- IF (cl_size = 8) AND (drive_no = 3) THEN
- BEGIN
-
- {DOS 2.0/2 SIDE HARD DISK}
- drive := $80; { 80H }
- biosread(fat_fill,drive,0,0,3,8);
- no_sect := 17; { 17}
- no_root := 4; { 4}
- no_side := 4; { 4}
- cl_size := 8; { 8}
- first_clust := 34; { 34}
- first_dir := 18; { 18}
- END
-
- ELSE
- BEGIN
- drive := drive_no-1;
-
- {read FAT ...side 0, track 0, sector 2}
-
- biosread(fat_fill,drive,0,0,2,2);
-
- CASE fat_fill[0] OF
-
- {DOS 2.0/2 SIDE }
- $FD : BEGIN
- no_sect := 9;
- no_root := 3.5;
- no_side := 2;
- cl_size := 2;
- first_clust := 8;
- first_dir := 5;
- END;
-
- {DOS 1.1/2 SIDE }
- $FF : BEGIN
- no_sect := 8;
- no_root := 3.5;
- no_side := 2;
- cl_size := 2;
- first_clust := 7;
- first_dir := 3;
- END;
-
- {DOS 2.0/1 SIDE }
- $FC : BEGIN
- no_sect := 9;
- no_root := 2;
- no_side := 1;
- cl_size := 1;
- first_clust := 8;
- first_dir := 5;
- END;
-
- {DOS 1.1/1 SIDE }
- $FE : BEGIN
- no_sect := 8;
- no_root := 2;
- no_side := 1;
- cl_size := 1;
- first_clust := 7;
- first_dir := 3;
- END;
-
- ELSE
- END;
- END;
-
-
- one_on := FALSE;
-
- IF compressed THEN
- WRITE(outfil,comp,LL8,short);
-
- cluster[1] := first_dir;
-
- dir_name[1] := '\';
- dir_num := 1;
- parent := 1;
- dir_point := 1;
- FOR i := 1 TO 50 DO
- BEGIN
- son[i] := 0;
- father[i] := 0;
- END;
-
- no_lines := 0;
- no_max := 60;
- IF compressed THEN
- no_max := 38;
- side_border := ' ';
- IF want_border THEN
- BEGIN
- no_max := no_max-2;
- side_border:= '|';
- END;
-
- border := side_border + fill_string(' ',77) + side_border ;
- left_border := side_border + fill_string(' ',2) ;
- right_border := fill_string(' ',2) + side_border ;
- top_border := fill_string('-',79) ;
-
- IF want_border THEN
- WRITELN(outfil,top_border);
-
- free_space := free_clusters*(cl_size*512.0);
-
- WRITELN(outfil,left_border,' ':30,'Free: ',free_space:7:0,' ':19,
- month:2,'/',date:2,'/',year:2,' ',right_border);
-
- no_lines := no_lines + 1;
-
- END;
-
- PROCEDURE menu(VAR response:INTEGER);
- BEGIN
- CLRSCR;
- GOTOXY(10,3);WRITELN('1) Go');
- GOTOXY(10,7);WRITELN('2) Change output defaults');
- GOTOXY(10,11);WRITELN('3) Change file defaults');
- GOTOXY(10,15);WRITELN('4) Stop');
-
- GOTOXY(1,20);WRITELN('Output defaults: output to ',outfil_name,
- ' border ',want_border,' compressed ',compressed);
-
- GOTOXY(1,22);WRITELN('File defaults: Drive ',drive_no,
- ' show hidden ',want_hidden,' show deleted ',want_deleted,
- ' show dir ',want_dir);
-
- GOTOXY(15,24);WRITE('Enter option ');READLN(response);
- CLRSCR;
-
- END;
-
- PROCEDURE display_menu;
- BEGIN
- CLRSCR;
-
- GOTOXY(1,1);WRITELN('Output defaults: output to ',outfil_name,
- ' border ',want_border,' compressed ',compressed);
-
- GOTOXY(5,5) ; WRITE(' Output to: ');READLN(outfil_name);
- GOTOXY(5,8) ; WRITE(' Want border: ');READLN(alpha);
- IF LENGTH(alpha) <> 0 THEN
- want_border := (alpha = 'y') OR (alpha = 'Y');
- GOTOXY(5,11) ; WRITE(' Compressed: ');READLN(alpha);
- IF LENGTH(alpha) <> 0 THEN
- compressed := (alpha = 'y') OR (alpha = 'Y');
-
- CLRSCR;
-
- END;
-
- PROCEDURE file_menu;
- BEGIN
- CLRSCR;
-
- GOTOXY(1,1);WRITELN('File defaults: Drive ',drive_no,
- ' show hidden ',want_hidden,' show deleted ',want_deleted,
- ' show dir ',want_dir);
-
-
- GOTOXY(5,5) ; WRITE(' Drive: ');READLN(drive_no);
- GOTOXY(5,8) ; WRITE(' Show hidden files: ');READLN(alpha);
- IF LENGTH(alpha) <> 0 THEN
- want_hidden := (alpha = 'y') OR (alpha = 'Y');
- GOTOXY(5,11) ; WRITE(' Show deleted files:');READLN(alpha);
- IF LENGTH(alpha) <> 0 THEN
- want_deleted:= (alpha = 'y') OR (alpha = 'Y');
- GOTOXY(5,14) ; WRITE(' Show directories: ');READLN(alpha);
- IF LENGTH(alpha) <> 0 THEN
- want_dir := (alpha = 'y') OR (alpha = 'Y');
-
- CLRSCR;
-
- END;
-
-
-
-
- BEGIN
-
- drive_no := 1;
- want_border := TRUE;
- compressed := TRUE;
- want_hidden := TRUE;
- want_deleted := FALSE;
- want_dir := FALSE;
- outfil_name := 'LPT1:';
-
-
-
- response := 1;
- WHILE response <> 4 DO
- BEGIN
- menu(response);
- IF response = 2 THEN
- display_menu;
- IF response = 3 THEN
- file_menu;
-
- IF response = 1 THEN
- BEGIN
- ASSIGN(outfil,outfil_name);
- REWRITE(outfil);
- get_free_space(free_clusters,total_clusters,cl_size,drive_no);
- getdate(year,month,date,hour,min) ;
- year := year - 1900;
- setup(drive_no);
-
- read_dir (dir,cluster[1],no_root);
- sort_dir (file_name,no_words);
-
- WHILE parent <> 0 DO
- BEGIN
-
- IF son[parent] <> 0 THEN
- BEGIN { step down to son }
-
- dir_point := son[parent];
- parent := dir_point;
-
-
- read_dir (dir,cluster[parent],1.0);
- sort_dir (file_name,no_words);
-
- END { then begin }
-
- ELSE
- BEGIN
-
- WHILE (son[parent] = 0) AND (parent <> 0) DO
- BEGIN { move to next son; or pop to parent }
-
- parent := father[dir_point];
-
- IF father[dir_point+1] = parent THEN
- son[parent] := dir_point + 1
-
- ELSE
-
- IF parent <> 0 THEN
- son[parent] := 0;
-
- dir_point := parent;
-
- END; { move to next son; or pop to parent }
- END; { else begin }
- END; { while parent <> 0 }
-
- FOR i := no_lines TO no_max-1 DO
- IF want_border THEN
- WRITELN(outfil,border);
-
- no_lines := 0;
- IF want_border THEN
- WRITELN(outfil,top_border);
- { CLRSCR; }
- WRITE(outfil,ff);
- CLOSE(outfil);
-
- END;
- END;
-
- end.